#include <string.h>

#include "Trabajo.h"

/* =============================================================================
 * Declaracion Atributos privados
 * =============================================================================
 */
struct Trabajo{
  int prioridad;
  int potenciaProceso;
  unsigned long int requerimientoMemoria;
  char* path;
  long int tiempoEjecucion;
};

typedef struct Trabajo* _tTrabajo;

/*==============================================================================
 * Definicion de metodos publicos
 *==============================================================================
 */
void trabajoCrear(tTrabajo* pTrabajo
                , int pPrioridad
                , int pPotenciaProceso
                , unsigned long int pRequerimientoMemoria
                , char* pPathEjecutable
                , tTiempo pTiempoEjecucion)
{
  _tTrabajo trabajo = (_tTrabajo) malloc (sizeof (struct Trabajo));

  if (trabajo)
  {
    trabajo->prioridad = pPrioridad;
    trabajo->potenciaProceso = pPotenciaProceso;
    trabajo->requerimientoMemoria = pRequerimientoMemoria;
    trabajo->tiempoEjecucion = pTiempoEjecucion;
    
    // Clono el path.
    trabajo->path = (char*) malloc (sizeof (char) * (strlen (pPathEjecutable) + 1));
    trabajo->path[0]='\0';
    strcat (trabajo->path, pPathEjecutable);
  }
  *pTrabajo = trabajo;
}                

//------------------------------------------------------------------------------

tTrabajo trabajoClonar(tTrabajo pTrabajo){

    tTrabajo clon = NULL;
    
    if (pTrabajo)
    {
        trabajoCrear(
            &clon
        ,   trabajoGetPrioridad(pTrabajo)
        ,   trabajoGetPotenciaProceso(pTrabajo)
        ,   trabajoGetRequerimientoMemoria(pTrabajo)
        ,   trabajoGetPathEjecutable(pTrabajo)
        ,   trabajoGetTiempoEjecucion(pTrabajo)
        );
    }
    return clon;
}

//------------------------------------------------------------------------------

int trabajoDestruir(tTrabajo pTrabajo){
    
    int val = DATO_ERROR;

    if (pTrabajo)
    {
        // Libero la memoria alocada para contener el string del path.
        free (((_tTrabajo)pTrabajo)->path);
        
        // Libero los recursos que consume la instancia de trabajo.
        free ((_tTrabajo) pTrabajo);
        
        val = DATO_OK;
    }
    return val;
}

//------------------------------------------------------------------------------

int trabajoGetPrioridad(tTrabajo pTrabajo){

  int val = -1;
  
  if (pTrabajo)
    val = ((_tTrabajo) pTrabajo)->prioridad;

  return val;
}

//------------------------------------------------------------------------------

int trabajoGetPotenciaProceso (tTrabajo pTrabajo){
  
  int potencia = -1;
  
  if (pTrabajo)
    potencia = ((_tTrabajo) pTrabajo)->potenciaProceso;

  return potencia;
}

//------------------------------------------------------------------------------

unsigned long int trabajoGetRequerimientoMemoria (tTrabajo pTrabajo){

  int memoria = 0;
  
  if (pTrabajo)
    memoria = ((_tTrabajo)pTrabajo)->requerimientoMemoria;

  return memoria;
}

//------------------------------------------------------------------------------

char* trabajoGetPathEjecutable (tTrabajo pTrabajo){
  
  char* val = "";

  if (pTrabajo)
    val = ((_tTrabajo) pTrabajo)->path;
    
  return val;
}

//------------------------------------------------------------------------------

tTiempo trabajoGetTiempoEjecucion(tTrabajo pTrabajo){
  
    int val = TIEMPO_INDEF;
  
    if (pTrabajo)
        val = ((_tTrabajo) pTrabajo)->tiempoEjecucion;
    
    return val;  
}

//------------------------------------------------------------------------------

tTiempo trabajoCorrer(tTrabajo pTrabajo, int pTiempo){

    tTiempo val = TIEMPO_INDEF;
    
    if (pTrabajo && pTiempo > 0)
    {
        ((_tTrabajo)pTrabajo)->tiempoEjecucion -=  pTiempo;
    
        if (trabajoGetTiempoEjecucion(pTrabajo) < 0)
        ((_tTrabajo)pTrabajo)->tiempoEjecucion =  0;
        
        val = ((_tTrabajo)pTrabajo)->tiempoEjecucion;
    }
    return val;
}

//------------------------------------------------------------------------------

tBool trabajoIgual (tTrabajo pTrabajoA, tTrabajo pTrabajoB){
    
    tBool igual = TRUE;
    
    if (pTrabajoA && pTrabajoB)
    {
        if (igual)
            igual = igual && !(strcmp (trabajoGetPathEjecutable(pTrabajoA), trabajoGetPathEjecutable(pTrabajoB)));
        
        if (igual)
            igual = igual && (trabajoGetPotenciaProceso(pTrabajoA) == trabajoGetPotenciaProceso(pTrabajoB));
        
        if (igual)
            igual = igual && (trabajoGetPrioridad(pTrabajoA) == trabajoGetPrioridad(pTrabajoB));
        
        if (igual)
            igual = igual && (trabajoGetRequerimientoMemoria(pTrabajoA) == trabajoGetRequerimientoMemoria(pTrabajoB));
        
        if (igual)
            igual = igual && (trabajoGetTiempoEjecucion(pTrabajoA) == trabajoGetTiempoEjecucion(pTrabajoB));        
    }
    else
        igual = FALSE;
    
    return igual;
}        

//------------------------------------------------------------------------------

void trabajoImprimir (tTrabajo pTrabajo, tOutStream pOutStream){
    
    if (pTrabajo && pOutStream)
    {
        fprintf(pOutStream
            , "[Path: %s][Potencia Proceso: %d][Prioridad: %d][Memora Requerida: %lu][Tiempo Ejecucion: %d]"
            ,trabajoGetPathEjecutable(pTrabajo)
            ,trabajoGetPotenciaProceso(pTrabajo)
            ,trabajoGetPrioridad(pTrabajo)            
            ,trabajoGetRequerimientoMemoria(pTrabajo)
            ,trabajoGetTiempoEjecucion(pTrabajo)
        );
    }
}


